package ru.megazlo.basemvc.config;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.hibernate.jpa.HibernatePersistenceProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import ru.megazlo.basemvc.core.GlobalUtil;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.util.Properties;

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories("ru.megazlo.basemvc.dao")
@EnableJpaAuditing
@ComponentScan("ru.megazlo.basemvc.dao.dto")
public class JpaConfig {

	private static final String PROPERTY_NAME_DATABASE_DRIVER = "db.driver";
	private static final String PROPERTY_NAME_DATABASE_PASSWORD = "db.password";
	private static final String PROPERTY_NAME_DATABASE_URL = "db.url";
	private static final String PROPERTY_NAME_DATABASE_USERNAME = "db.username";

	private static final String PROPERTY_NAME_HIBERNATE_DIALECT = "hibernate.dialect";
	private static final String PROPERTY_NAME_HIBERNATE_SHOW_SQL = "hibernate.show_sql";
	private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN = "entitymanager.packages.to.scan";

	static Logger log = LogManager.getLogger(JpaConfig.class.getName());

	@Resource
	private Environment env;

	/*
	<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"
          p:driverClassName="net.sourceforge.jtds.jdbc.Driver" p:url="jdbc:jtds:sqlserver://localhost:1433/mvcdb"
          p:username="sa" p:password="qwepoi123098"/>
	* */

	@Bean
	public DataSource dataSource() {
		DriverManagerDataSource dataSource = new DriverManagerDataSource();
		dataSource.setDriverClassName("net.sourceforge.jtds.jdbc.Driver"/*env.getRequiredProperty(PROPERTY_NAME_DATABASE_DRIVER)*/);
		dataSource.setUrl("jdbc:jtds:sqlserver://localhost:1433/mvcdb"/*env.getRequiredProperty(PROPERTY_NAME_DATABASE_URL)*/);
		dataSource.setUsername("sa"/*env.getRequiredProperty(PROPERTY_NAME_DATABASE_USERNAME)*/);
		dataSource.setPassword("qwepoi123098"/*env.getRequiredProperty(PROPERTY_NAME_DATABASE_PASSWORD)*/);
		return dataSource;
	}

	@Bean
	public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
		LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
		entityManagerFactoryBean.setDataSource(dataSource());
		entityManagerFactoryBean.setPersistenceProviderClass(HibernatePersistenceProvider.class);
		entityManagerFactoryBean.setPackagesToScan("ru.megazlo.basemvc.dao.dto"/*env.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN)*/);
		entityManagerFactoryBean.setJpaProperties(hibProperties());
		return entityManagerFactoryBean;
	}

	private Properties hibProperties() {
		Properties properties = new Properties();
		properties.put(PROPERTY_NAME_HIBERNATE_DIALECT, "org.hibernate.dialect.SQLServerDialect"/*env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_DIALECT)*/);
		properties.put("hbm2ddl.auto", "create-drop "/*env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_DIALECT)*/);
		properties.put("hibernate.cache.use_second_level_cache", "true");
		properties.put("hibernate.cache.use_query_cache", "true");
		properties.put("hibernate.cache.region.factory_class", "org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory");//для распределенных EhCacheProvider
		if (GlobalUtil.IsDebug()) {
			log.debug("in debug mode enetered");
			properties.put("hibernate.show_sql", "true");
			//properties.put("hibernate.generate_statistics", "true");
		}
		//properties.put(PROPERTY_NAME_HIBERNATE_SHOW_SQL, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_SHOW_SQL));
		return properties;
	}

	@Bean
	public JpaTransactionManager transactionManager() {
		JpaTransactionManager transactionManager = new JpaTransactionManager();
		transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
		return transactionManager;
	}
}
